package com.kymatrix.kycarbon.xsmd.system.server.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.kymatrix.kycarbon.xsmd.system.server.dao.ModuleMapper;
import com.kymatrix.kycarbon.xsmd.system.server.dao.RoleMapper;
import com.kymatrix.kycarbon.xsmd.system.server.dao.RoleModuleMapper;
import com.kymatrix.kycarbon.xsmd.system.server.dao.UserRoleMapper;
import com.kymatrix.kycarbon.xsmd.system.server.model.entity.RoleEntity;
import com.kymatrix.kycarbon.xsmd.system.server.model.entity.RoleModuleRelationEntity;
import com.kymatrix.kycarbon.xsmd.system.server.model.entity.UserRoleRelationEntity;
import com.kymatrix.kycarbon.xsmd.system.server.model.form.role.InsertRoleReq;
import com.kymatrix.kycarbon.xsmd.system.server.model.form.role.ListQueryRoleResp;
import com.kymatrix.kycarbon.xsmd.system.server.model.form.role.PageQueryRoleReq;
import com.kymatrix.kycarbon.xsmd.system.server.model.form.role.PageQueryRoleResp;
import com.kymatrix.kycarbon.xsmd.system.server.model.form.role.QueryRoleResp;
import com.kymatrix.kycarbon.xsmd.system.server.model.form.role.UpdateRoleReq;
import com.kymatrix.kycarbon.xsmd.system.server.service.IRoleService;
import com.kymatrix.kycarbon.xsmd.common.constants.Constant;
import com.kymatrix.kycarbon.xsmd.common.exception.BusinessException;
import java.util.List;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Primary
public class RoleServiceImpl extends ServiceImpl<RoleMapper, RoleEntity> implements IRoleService {

    @Resource
    private UserRoleMapper userRoleMapper;
    
    @Resource
    private RoleModuleMapper roleModuleMapper;
    @Resource
    private ModuleMapper moduleMapper;

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public void save(InsertRoleReq req) {
        RoleEntity roleEntity = RoleEntity.builder().name(req.getName()).build();
        this.baseMapper.insert(roleEntity);
        if (CollectionUtil.isNotEmpty(req.getModuleIdList())) {
            for (String moduleId : req.getModuleIdList()) {
                if (moduleMapper.selectById(moduleId) == null) {
                    throw new BusinessException("模块id不存在");
                }
                RoleModuleRelationEntity entity = new RoleModuleRelationEntity();
                entity.setRoleId(roleEntity.getId());
                entity.setModuleId(moduleId);
                this.roleModuleMapper.insert(entity);
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public void updateRole(UpdateRoleReq req) {
        RoleEntity roleEntity = this.baseMapper.selectById(req.getId());
        if (roleEntity != null) {
            roleEntity.setName(req.getName());
            this.baseMapper.updateById(roleEntity);
        } else {
            throw new BusinessException("角色不存在");
        }
        this.roleModuleMapper.deleteByRoleId(req.getId());
        if (CollectionUtil.isNotEmpty(req.getModuleIdList())) {
            for (String moduleId : req.getModuleIdList()) {
                RoleModuleRelationEntity entity = new RoleModuleRelationEntity();
                entity.setRoleId(roleEntity.getId());
                entity.setModuleId(moduleId);
                this.roleModuleMapper.insert(entity);
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public void deleteRole(String id) {
        RoleEntity roleEntity = this.baseMapper.selectById(id);
        if (roleEntity == null) {
            return;
        }
        List<UserRoleRelationEntity> list = this.userRoleMapper.selectByRoleId(id);
        if (CollectionUtil.isNotEmpty(list)) {
            throw new BusinessException("角色绑定了用户，请先解绑");
        }
        roleEntity.setDeleted(Constant.DEL_FLAG_DELETE);
        this.baseMapper.updateById(roleEntity);
        this.roleModuleMapper.deleteByRoleId(id);
    }

    @Override
    public Page<PageQueryRoleResp> pageQuery(PageQueryRoleReq req) {
        Page<PageQueryRoleResp> listQueryRoleRespPage = this.baseMapper.pageQuery(
                new Page<>(req.getCurrent(), req.getPageSize()), req.getName());
        for (PageQueryRoleResp roleResp : listQueryRoleRespPage.getRecords()) {
            List<UserRoleRelationEntity> userRoleList = this.userRoleMapper.selectByRoleId(roleResp.getId());
            roleResp.setUserCount((long) userRoleList.size());
        }
        return listQueryRoleRespPage;
    }

    @Override
    public QueryRoleResp getRole(String id) {
        RoleEntity roleEntity = this.baseMapper.selectById(id);
        List<RoleModuleRelationEntity> roleModuleList = this.roleModuleMapper.selectByRoleIds(Lists.newArrayList(id));
        QueryRoleResp res = new QueryRoleResp();
        res.setId(roleEntity.getId());
        res.setName(roleEntity.getName());
        res.setModuleIdList(
                roleModuleList.stream().map(RoleModuleRelationEntity::getModuleId).collect(Collectors.toList()));
        return res;
    }

    @Override
    public List<ListQueryRoleResp> list(String name) {
        return this.baseMapper.list(name);
    }

    @Override
    public List<RoleEntity> selectByIds(List<String> roleIdList) {
        return this.baseMapper.selectByIds(roleIdList);
    }
}
